﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Net;
using System.Text;
using System.IO;

namespace NotificationPusher.Services
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class NotificationService
    {
        [OperationContract]
        public string SendToastNotification(
            string subscriptionUri,
            string title,
            string content)
        {
            // The URI that the Push Notification Service returns to the Push Client when creating a notification channel.
            HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

            // HTTP POST is the only allowed method to send the notification.
            sendNotificationRequest.Method = "POST";

            // The optional custom header X-MessageID uniquely identifies a notification message. If it is present, the // same value is returned in the notification response. It must be a string that contains a UUID.
            sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
            sendNotificationRequest.ContentType = "text/xml";
            sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
            sendNotificationRequest.Headers.Add("X-NotificationClass", "2");

            string toastMessageFormat = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                                        "<wp:Notification xmlns:wp=\"WPNotification\">" +
                                           "<wp:Toast>" +
                                              "<wp:Text1>{0}</wp:Text1>" +
                                              "<wp:Text2>{1}</wp:Text2>" +
                                           "</wp:Toast>" +
                                        "</wp:Notification>";
            string tileMessage = string.Format(toastMessageFormat, title, content);

            // Sets the notification payload to send.
            byte[] payload = Encoding.UTF8.GetBytes(tileMessage);

            // Sets the web request content length.
            sendNotificationRequest.ContentLength = payload.Length;

            using (Stream requestStream = sendNotificationRequest.GetRequestStream())
            {
                requestStream.Write(payload, 0, payload.Length);
            }

            // Sends the notification and gets the response.
            HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
            string notificationStatus = response.Headers["X-NotificationStatus"];
            string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
            string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

            return string.Format(
                "Notification: {0} Channel: {1} Device: {2}",
                notificationStatus,
                notificationChannelStatus,
                deviceConnectionStatus);
        }

        [OperationContract]
        public string SendTileNotification(
            string subscriptionUri,
            string title,
            string count,
            string imageUrl)
        {
            // The URI that the Push Notification Service returns to the Push Client when creating a notification channel.
            HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

            // HTTP POST is the only allowed method to send the notification.
            sendNotificationRequest.Method = "POST";

            // The optional custom header X-MessageID uniquely identifies a notification message. If it is present, the // same value is returned in the notification response. It must be a string that contains a UUID.
            sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
            sendNotificationRequest.ContentType = "text/xml";
            sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");
            sendNotificationRequest.Headers.Add("X-NotificationClass", "1");

            string imageFormat = string.Empty;
            if (string.IsNullOrEmpty(imageUrl) == false)
            {
                imageFormat = string.Format("<wp:BackgroundImage>{0}</wp:BackgroundImage>", imageUrl);
            }

            string messageFormat =
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<wp:Notification xmlns:wp=\"WPNotification\">" +
                    "<wp:Tile>" +
                        "{2}" + /// Image
                        "<wp:Count>{1}</wp:Count>" +
                        "<wp:Title>{0}</wp:Title>" +
                    "</wp:Tile>" +
                "</wp:Notification>";

            string tileMessage = string.Format(messageFormat, title, count, imageFormat);

            // Sets the notification payload to send.
            byte[] payload = Encoding.UTF8.GetBytes(tileMessage);

            // Sets the web request content length.
            sendNotificationRequest.ContentLength = payload.Length;

            using (Stream requestStream = sendNotificationRequest.GetRequestStream())
            {
                requestStream.Write(payload, 0, payload.Length);
            }

            // Sends the notification and gets the response.
            HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
            string notificationStatus = response.Headers["X-NotificationStatus"];
            string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
            string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

            return string.Format(
                "Notification: {0} Channel: {1} Device: {2}",
                notificationStatus,
                notificationChannelStatus,
                deviceConnectionStatus);
        }

        [OperationContract]
        public string SendRawNotification(
            string subscriptionUri,
            string message)
        {
            // The URI that the Push Notification Service returns to the Push Client when creating a notification channel.
            HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

            // HTTP POST is the only allowed method to send the notification.
            sendNotificationRequest.Method = "POST";

            // The optional custom header X-MessageID uniquely identifies a notification message. If it is present, the // same value is returned in the notification response. It must be a string that contains a UUID.
            sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
            sendNotificationRequest.Headers.Add("X-NotificationClass", "3");

            // Sets the notification payload to send.
            byte[] payload = Encoding.UTF8.GetBytes(message);

            // Sets the web request content length.
            sendNotificationRequest.ContentLength = payload.Length;

            using (Stream requestStream = sendNotificationRequest.GetRequestStream())
            {
                requestStream.Write(payload, 0, payload.Length);
            }

            // Sends the notification and gets the response.
            HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
            string notificationStatus = response.Headers["X-NotificationStatus"];
            string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
            string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

            return string.Format(
                "Notification: {0} Channel: {1} Device: {2}",
                notificationStatus,
                notificationChannelStatus,
                deviceConnectionStatus);
        }
    }
}
